package com.admin.system.service;

import java.util.ArrayList;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import com.admin.system.common.SystemConstant;
import com.admin.system.dao.SystemResourceMapper;
import com.admin.system.entity.SystemResource;

@Service
public class SystemResourceService {
	private final static Logger log = LoggerFactory.getLogger(SystemResourceService.class);
	@Autowired
	SystemResourceMapper resourceMapper;

	/**
	 * 获取可用菜单（不含根节点）
	 *
	 * @return
	 */
	public List<SystemResource> querySystemResources(Integer userId) {
		List<SystemResource> resources = resourceMapper.queryUserMenu(userId);
		return structureTree(true, resources);

	}

	/**
	 * 查询全部菜单树（含根节点）
	 *
	 * @return
	 */
	public SystemResource getAllResourceTree() {
		List<SystemResource> resourceList = resourceMapper.querySystemResource(false, null);
		List<SystemResource> resourceTree = structureTree(false, resourceList);
		SystemResource resource = resourceTree.get(0);
		return resource;
	}

	/**
	 * 使用父节点ID获取子节点列表
	 * 
	 * @param pid
	 * @return
	 */
	public List<SystemResource> getResourceByPid(Integer pid) {
		List<SystemResource> resourceList = resourceMapper.queryChildrenResource(pid, null);
		return resourceList;
	}

	/**
	 * 保存
	 *
	 * @param resource
	 */
	public void save(SystemResource resource) {
		if (resource.getId() == null) {
			resourceMapper.insert(resource);
		} else {
			resourceMapper.updateByPrimaryKeySelective(resource);
		}
	}

	/**
	 * 递归删除菜单及其子节点
	 *
	 * @param resource
	 */
	public void delete(SystemResource resource) {
		recursionDelete(resource);
	}

	/**
	 * 通过URL获取菜单信息
	 *
	 * @param url
	 * @return
	 */
	public SystemResource queryResourceByUrl(String url) {
		return resourceMapper.queryResourceByUrl(url);

	}

	/**
	 * 递归删除菜单
	 *
	 * @param resource
	 */
	private void recursionDelete(SystemResource resource) {
		List<SystemResource> childrenList = resourceMapper.queryChildrenResource(resource.getId(), null);
		if (!CollectionUtils.isEmpty(childrenList)) {
			for (SystemResource children : childrenList) {
				recursionDelete(children);
			}
		}
		resourceMapper.deleteByPrimaryKey(resource.getId());
	}

	/**
	 * 构建菜单树结构
	 *
	 * @param excludeRoot 是否排除根节点
	 * @return
	 */
	private List<SystemResource> structureTree(Boolean excludeRoot, List<SystemResource> resources) {
		// 第一级菜单
		List<SystemResource> topResource = new ArrayList<>();
		// 子菜单
		List<SystemResource> childResource = new ArrayList<>();
		// 进行分类
		for (SystemResource systemResource : resources) {
			if (excludeRoot) {
				if (systemResource.getPid() == 0) {
					topResource.add(systemResource);
				} else {
					childResource.add(systemResource);
				}
			} else {
				if (systemResource.getPid() == null) {
					// 根节点默认打开
					topResource.add(systemResource);
					systemResource.setOpen(true);
				} else {
					childResource.add(systemResource);
				}
			}

		}
		// 给所有子菜单寻找上级菜单
		for (SystemResource child : childResource) {
			for (SystemResource parent : resources) {
				if (child.getPid().equals(parent.getId())) {
					if (parent.getChildren() == null) {
						parent.setIsParent(true);
						parent.setChildren(new ArrayList<>());
					}
					parent.getChildren().add(child);
					break;
				}
			}
		}
		return topResource;
	}

	private List<Integer> removeAll(List<Integer> source, List<Integer> target) {
		List<Integer> result = new ArrayList<>();
		for (Integer s : source) {
			if (!target.contains(s)) {
				result.add(s);
			}
		}
		return result;
	}

	public List<SystemResource> getResources(Boolean excludeRoot, Integer status) {
		return resourceMapper.querySystemResource(excludeRoot, status);
	}

	/**
	 * 分配权限
	 *
	 * @param roleId
	 * @param submission
	 */
	public void assignResources(Integer roleId, List<Integer> submission) {
		List<Integer> assigned = resourceMapper.assignedIds(roleId);
		List<Integer> add = removeAll(submission, assigned);
		List<Integer> remove = removeAll(assigned, submission);
		if (!add.isEmpty()) {
			resourceMapper.addAllocation(roleId, add);
		}
		if (!remove.isEmpty()) {
			resourceMapper.removeAllocation(roleId, remove);
		}
	}

	/**
	 * 查询被分配的权限
	 *
	 * @param roleId
	 * @return
	 */
	public List<SystemResource> assignedResources(Integer roleId) {
		List<SystemResource> resources = resourceMapper.querySystemResource(true, SystemConstant.ResourceStatus.USABLE);
		List<SystemResource> resourcesTree = structureTree(true, resources);
		//查询已被分配的资源
		List<Integer> assigned = resourceMapper.assignedIds(roleId);

		matchingResources(resourcesTree, assigned);
		log.info(resources.toString());
		return resourcesTree;
	}

	/**
	 * 匹配分配给角色的权限
	 *
	 * @param resources
	 * @param assigned
	 */
	private boolean matchingResources(List<SystemResource> resources, List<Integer> assigned) {
		boolean parentHalfCheck = false;
		for (SystemResource resource : resources) {
			if (null != resource.getChildren() && !resource.getChildren().isEmpty()) {
				parentHalfCheck = matchingResources(resource.getChildren(), assigned);
			}
			if (assigned.contains(resource.getId())) {
				resource.setChecked(true);
				parentHalfCheck = true;
			}
		}
		return parentHalfCheck;
	}
}